r"""
此模块中定义的常量为：

string.ascii_letters
    下文所述 ascii_lowercase 和 ascii_uppercase 常量的拼连。 该值不依赖于语言区域。

string.ascii_lowercase
    小写字母 'abcdefghijklmnopqrstuvwxyz'。 该值不依赖于语言区域，不会发生改变。

string.ascii_uppercase
    大写字母 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'。 该值不依赖于语言区域，不会发生改变。

string.digits
    字符串 '0123456789'。

string.hexdigits
    字符串 '0123456789abcdefABCDEF'。

string.octdigits
    字符串 '01234567'。

string.punctuation
    由在 C 区域设置中被视为标点符号的 ASCII 字符所组成的字符串: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~.

string.printable
    由被视为可打印符号的 ASCII 字符组成的字符串。 这是 digits, ascii_letters, punctuation 和 whitespace 的总和。

string.whitespace
    由被视为空白符号的 ASCII 字符组成的字符串。 其中包括空格、制表、换行、回车、进纸和纵向制表符。
"""
import string


class CustomFormatter(string.Formatter):
    """重写Formatter类的方法可以实现自定义字符串格式化过程"""

    def format(*args, **kwargs):
        """首要的 API 方法。 它接受一个格式字符串和任意一组位置和关键字参数。它只是一个调用 vformat() 的包装器。"""

        if not args:
            raise TypeError("descriptor 'format' of 'Formatter' object "
                            "needs an argument")
        self, *args = args  # allow the "self" keyword be passed
        try:
            format_string, *args = args  # allow the "format_string" keyword be passed
        except ValueError:
            raise TypeError("format() missing 1 required positional "
                            "argument: 'format_string'") from None
        return self.vformat(format_string, args, kwargs)

    def vformat(self, format_string, args, kwargs):
        """
        此函数执行实际的格式化操作。 它被公开为一个单独的函数，用于需要传入一个预定义字母作为参数，而不是使用 *args 和 **kwargs
        语法将字典解包为多个单独参数并重打包的情况。 vformat() 完成将格式字符串分解为字符数据和替换字段的工作。 它会调用下文所述
        的几种不同方法。
        """

        used_args = set()
        result, _ = self._vformat(format_string, args, kwargs, used_args, 2)
        self.check_unused_args(used_args, args, kwargs)
        return result


s = "{name} is {age} year old"
print(s.format(name='tom', age='18'))

formatter = CustomFormatter()
print(formatter.format(s, name='jack', age='12'))
